<?php

if (!defined('__COLA_DIR__')) exit;

/**
 * 表单处理帮手
 *
 * @author edikud
 * @package Form
 * @copyright Copyright (c) 2019 Cola (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */

class Form extends Element
{
    /** 表单post方法 */
    const POST_METHOD = 'post';

    /** 表单get方法 */
    const GET_METHOD = 'get';

    /** 标准编码方法 */
    const STANDARD_ENCODE = 'application/x-www-form-urlencoded';

    /** 混合编码 */
    const MULTIPART_ENCODE = 'multipart/form-data';

    /** 文本编码 */
    const TEXT_ENCODE= 'text/plain';

    /**
     * 输入元素列表
     *
     * @access private
     * @var array
     */
    private $_inputs = array();

	private $prefix = 'cola-';
	
    /**
     * 构造函数,设置基本属性
     *
     * @access public
     */
    public function __construct($action = NULL, $prefix = NULL)
    {
        /** 设置表单标签 */
        parent::__construct('form');
		
		$prefix && $this->setPrefix($prefix);
		
		$this->setAttr('class', $this->prefix . 'form');

        /** 关闭自闭合 */
        $this->setClose(false);

        /** 设置表单属性 */
        $this->setAction($action);
        $this->setMethod(self::POST_METHOD);
        $this->setEncodeType(self::STANDARD_ENCODE);
    }

    /**
     * 设置表单编码方案
     *
     * @access public
     * @param string $prefix 编码方法
     * @return Form
     */
    public function setPrefix($prefix)
    {
        $this->prefix = $prefix;
        return $this;
    }	
	
    /**
     * 设置表单编码方案
     *
     * @access public
     * @param string $enctype 编码方法
     * @return Form
     */
    public function setEncodeType($enctype)
    {
        $this->setAttr('enctype', $enctype);
        return $this;
    }

    /**
     * 增加输入元素
     *
     * @access public
     * @param Form $input 输入元素
     * @param string $after 在某个元素之后
     * @return Form
     */
    public function addInput(Form_Group $input, $after = NULL)
    {
		$this->_inputs[$input->name] = $input;
		$this->set($input, $input->name, $after);
        return $this;
    }

    /**
     * 获取输入项
     *
     * @access public
     * @param string $name 输入项名称
     * @return mixed
     */
    public function getInput($name)
    {
        return $this->_inputs[$name];
    }

    /**
     * 获取所有输入项的提交值
     *
     * @access public
     * @return array
     */
    public function getAllRequest()
    {
        $result = array();
        $source = (self::POST_METHOD == $this->getAttr('method')) ? $_POST : $_GET;
        foreach ($this->_inputs as $name => $input) 
		{
            $result[$name] = isset($source[$name]) ? $source[$name] : NULL;
        }
        return $result;
    }

    /**
     * 设置表单提交方法
     *
     * @access public
     * @param string $method 表单提交方法
     * @return Form
     */
    public function setMethod($method)
    {
        $this->setAttr('method', $method);
        return $this;
    }

    /**
     * 设置表单提交目的
     *
     * @access public
     * @param string $action 表单提交目的
     * @return Form
     */
    public function setAction($action)
    {
        $this->setAttr('action', $action);
        return $this;
    }

    /**
     * 获取此表单的所有输入项固有值
     *
     * @access public
     * @return array
     */
    public function getValues()
    {
        $values = array();
        foreach ($this->_inputs as $name => $input) 
		{
            $values[$name] = $input->value;
        }
        return $values;
    }

    /**
     * 获取此表单的所有输入项
     *
     * @access public
     * @return array
     */
    public function getInputs()
    {
        return $this->_inputs;
    }

    /**
     * 获取提交数据源
     *
     * @access public
     * @param array $params 数据参数集
     * @return array
     */
    public function getParams(array $params)
    {
        $result = array();
        $source = (self::POST_METHOD == $this->getAttr('method')) ? $_POST : $_GET;
        foreach ($params as $param) 
		{
            $result[$param] = isset($source[$param]) ? $source[$param] : NULL;
        }

        return $result;
    }

    /**
     * 验证表单
     *
     * @access public
     * @return mixed
     */
    public function validate()
    {
        $validator = new Validate();
        $rules = array();

        foreach ($this->_inputs as $name => $input) 
		{
            $rules[$name] = $input->rules;
        }

        /** 表单值 */
        $formData = $this->getParams(array_keys($rules));
        return $validator->setBreak()->run($formData, $rules); 
    }

}
